import axios from 'axios'
import type { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'

interface MyIntercetpors<T = AxiosResponse> {
  requestSuccessFn?: (config: AxiosRequestConfig) => AxiosRequestConfig
  requestFailureFn?: (err: any) => any
  responseSuccessFn?: (res: T) => T
  resPonseFailureFn?: (err: any) => any
}

interface MyRequestConfig<T = AxiosResponse> extends AxiosRequestConfig {
  interceptors?: MyIntercetpors<T>
}

class MyAxios {
  instance: AxiosInstance
  constructor(config: MyRequestConfig) {
    this.instance = axios.create(config)

    // 全局请求拦截器
    this.instance.interceptors.request.use(
      (config) => {
        // 如果开启 token 认证
        // if (axiosConfig.useTokenAuthorization) {
        //   config.headers["Authorization"] = localStorage.getItem("token"); // 请求头携带 token
        // }

        // 设置请求头
        return config
      },
      (error) => {
        Promise.reject(error)
      }
    )
    // 全局响应拦截器
    this.instance.interceptors.response.use(
      (res) => {
        let data = res.data
        // 处理自己的业务逻辑，比如判断 token 是否过期等等
        // 代码块
        return data
      },
      (error) => {
        let message = ''
        if (error && error.response) {
          switch (error.response.status) {
            case 302:
              message = '接口重定向了！'
              break
            case 400:
              message = '参数不正确！'
              break
            case 401:
              message = '您未登录，或者登录已经超时，请先登录！'
              break
            case 403:
              message = '您没有权限操作！'
              break
            case 404:
              message = `请求地址出错: ${error.response.config.url}`
              break
            case 408:
              message = '请求超时！'
              break
            case 409:
              message = '系统已存在相同数据！'
              break
            case 500:
              message = '服务器内部错误！'
              break
            case 501:
              message = '服务未实现！'
              break
            case 502:
              message = '网关错误！'
              break
            case 503:
              message = '服务不可用！'
              break
            case 504:
              message = '服务暂时无法访问，请稍后再试！'
              break
            case 505:
              message = 'HTTP 版本不受支持！'
              break
            default:
              message = '异常问题，请联系管理员！'
              break
          }
        }
        return Promise.reject(message)
      }
    )
    // 实例拦截器
    if (config.interceptors) {
      this.instance.interceptors.request.use(
        config.interceptors.requestSuccessFn as any,
        config.interceptors.requestFailureFn
      )

      this.instance.interceptors.response.use(
        config.interceptors.responseSuccessFn,
        config.interceptors.responseSuccessFn
      )
    }
  }

  request<T = any>(config: MyRequestConfig<T>) {
    // 方法拦截器
    if (config.interceptors?.requestSuccessFn) {
      config = config.interceptors.requestSuccessFn(config)
    }

    return new Promise<T>((resolve, reject) => {
      this.instance
        .request<any, T>(config)
        .then((res) => {
          if (config.interceptors?.responseSuccessFn) {
            res = config.interceptors.responseSuccessFn(res)
          }
          resolve(res)
        })
        .catch((err) => {
          reject(err)
        })
    })
  }

  get<T = any>(config: MyRequestConfig<T>) {
    return this.instance<any, T>({ ...config, method: 'GET' })
  }
  post<T = any>(config: MyRequestConfig<T>) {
    return this.instance<any, T>({ ...config, method: 'POST' })
  }
  patch<T = any>(config: MyRequestConfig<T>) {
    return this.instance<any, T>({ ...config, method: 'patch' })
  }
  delete<T = any>(config: MyRequestConfig<T>) {
    return this.instance<any, T>({ ...config, method: 'DELETE' })
  }
}
export default MyAxios
